package com.archermind.style.service;

import com.archermind.style.bean.InstanceStyle;
import com.archermind.style.bean.StyleType;
import com.archermind.style.pojo.ElementEnum;
import com.archermind.style.pojo.RuleText;
import com.feng.fengDUtil.BaseService;
import com.archermind.style.util.ByteUtil;
import com.archermind.style.util.Search;
import com.feng.fengDUtil.Page;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class StyleTypeService extends BaseService {

    private static final Logger log = LoggerFactory.getLogger(StyleTypeService.class);

    //导入样式时专用
    public static ThreadLocal<Map<String,StyleType>> styleMap = new ThreadLocal<Map<String,StyleType>>();

    //生成xml时，缓存dash_line 和 text 的styleType。
    public static ThreadLocal<Map<Integer,StyleType>> textStyleThreadLocal = new ThreadLocal<Map<Integer,StyleType>>();

    public Page query(Page page, Search search) {
        ArrayList params = new ArrayList();
        String sql = "select * from style_type u where 1=1 ";
        if(search.getElement()!=null){
            sql+=" and element = ?";
            params.add(search.getElement().name());
        }

        sql+="  order by name asc";
        findPageList(StyleType.class,sql,page,params.toArray());
        return page;
    }

    public boolean isUnique(String name, Integer id, String element) {
        List params = new ArrayList<>();
        String sql = "select 1 from style_type where name = ? and element = ? ";
        params.add(name);
        params.add(element);
        if(id!=null){
            sql += " and id != ?";
            params.add(id);
        }
        Long one = sql(sql).one(Long.class, params.toArray());
        return one == null;
    }

    /**
     * 判断样式名是否重复
     * @param text
     * @param id
     * @param element
     * @return
     */
    public boolean isUniqueText(String text, Integer id, String element) {
        List params = new ArrayList<>();
        String sql = "select 1 from style_type where text = ? and element = ? ";
        params.add(text);
        params.add(element);
        if(id!=null){
            sql += " and id != ?";
            params.add(id);
        }
        Long one = sql(sql).one(Long.class, params.toArray());
        return one == null;
    }

    public List<StyleType> listByElement(ElementEnum ele,Integer instanceId,boolean discardEmptyRule){
        ArrayList params = new ArrayList();
        String sql = "select s.*,i.tagForModify,i.textTag,i.textTypeId,t.name textName,t.code textStyleID from style_type s " +
                " left join instance_style i on s.id = i.styleTypeId and i.instanceId = ? " +
                " left join style_type t on t.id = i.textTypeId" +
                " where s.element = ? " ;
        params.add(instanceId);
        params.add(ele.name());
        if(discardEmptyRule){
            sql += " and exists (select 1 from rule_"+ele.name() +" u where u.instanceId = ? and u.styleTypeId = s.id)";
            params.add(instanceId);
        }
         sql+=  " order by s.code asc";
        return sql(sql).list(StyleType.class,params.toArray());
    }

    public StyleType getFullStyleType(Integer instanceId,Integer styleTypeId){
        String sql = "select s.*,i.tagForModify,i.textTag,i.textTypeId,t.name textName,t.code textStyleID from style_type s " +
                " left join instance_style i on s.id = i.styleTypeId and i.instanceId = ? " +
                " left join style_type t on t.id = i.textTypeId where s.id = ?";
        return sql(sql).one(StyleType.class,instanceId,styleTypeId);
    }

    /**
     * 导出xml时，获取点线路牌 样式对应的 文本样式
     * @param textStyleTypeId 文本样式id
     * @return
     */
    public StyleType getExistsTextStyle(Integer textStyleTypeId){
        StyleType textStyle = null;
        if(textStyleTypeId!=null){
            textStyle =   textStyleThreadLocal.get().get(textStyleTypeId);
        }
        return textStyle;
    }

    /**
     * 导出xml时，获取点线路牌 样式对应的 文本样式
     * @param element 样式类型
     * @return
     */
    public void getStyleTypeMapByElements(String ... element) {
        if(textStyleThreadLocal.get()==null){
            List<StyleType> list = sql("select * from style_type where element in ("+genePlaceHolders(element.length)+")").list(StyleType.class,element);
            Map<Integer,StyleType> map = new HashMap<>();
            for(StyleType styleType:list){
                map.put(styleType.getId(),styleType);
            }
            textStyleThreadLocal.set(map);
        }
    }

    public StyleType checkAndSaveTextType(RuleText text) {
        Integer instanceId = text.getInstanceId();
        Integer styleTypeId = text.getStyleTypeId();
        StyleType styleType = getFullStyleType(instanceId,styleTypeId);
        if(styleType.getTextTypeId()==null){
             StyleType textStyleType = new StyleType();
            textStyleType.setName(styleType.getName()+"_ctext");
            textStyleType.setElement(ElementEnum.text);
            saveOrUpdate(textStyleType);
            InstanceStyle instanceStyle = sql("select * from instance_style where instanceId = ? and styleTypeId = ? ").one(InstanceStyle.class, text.getInstanceId(),text.getStyleTypeId());
            if(instanceStyle == null){
                instanceStyle = new InstanceStyle();
                instanceStyle.setInstanceId(text.getInstanceId());
                instanceStyle.setStyleTypeId(styleTypeId);
                instanceStyle.setTextTypeId(textStyleType.getId());
                insert(instanceStyle);
            }else {
                sql("update instance_style set textTypeId = ? where instanceId = ? and styleTypeId = ? ").update(new Object[]{textStyleType.getId(),instanceId,styleTypeId});
            }
            return textStyleType;
        }else {
            return selectById(StyleType.class,styleType.getTextTypeId());
        }
    }

    public List<StyleType> listByElement(ElementEnum ele,Integer instanceId){
        return listByElement(ele,instanceId,false);
    }

    public void saveOrUpdate(StyleType bean) {
        if(bean.getCode() == null){
            Long maxCode = sql("select (ifnull(max(code),0)+1) from style_type where element = ?").one(Long.class,bean.getElement().toString());
            bean.setCode(maxCode.intValue());
        }
        super.saveOrUpdate(bean);
    }

    public ArrayList processXMLDom(Element root) {
        ArrayList conflictList = new ArrayList();
        Element aliasStyleDefine = root.element("AliasStyleDefine");
        for(ElementEnum element:ElementEnum.values()){
            Element node = aliasStyleDefine.element(element.getTypeTag());
            List<Element> list = node.elements("AliasItem");
            for(Element one : list){
                String name = one.attribute("AliasName").getValue();
                Integer code = ByteUtil.parseInteger(one.attribute("StyleID").getValue());

                StyleType bean =  sql("select * from style_type where element = ? and name = ? ").one(StyleType.class,element.name(),name);
                if(bean!=null && !bean.getCode().equals(code)){
                    conflictList.add(element.getName()+"样式："+name+"，原StyleID："+bean.getCode()+" vs ："+code);
                    continue;
                }
                if(bean==null){
                    bean = new StyleType(element,name,code);
                    super.insert(bean);
                }
                styleMap.get().put(element.name()+"#"+name,bean);
            }
        }

        //保存图标样式
        Element AliasIconStyleDefine = aliasStyleDefine.element("AliasIconStyleDefine");
        List<Element> iconStyles = AliasIconStyleDefine.elements("AliasItem");
        for(Element one : iconStyles){
            String name = one.attribute("AliasName").getValue();
            Integer code = ByteUtil.parseInteger(one.attribute("StyleID").getValue());
            StyleType bean = new StyleType(null,name,code);
            styleMap.get().put("icon#"+name,bean);
        }
        return conflictList;
    }

    public StyleType getOrInsertLineStyle(String oriLineStyleName,String textStyleName){
        if(textStyleName.endsWith("_text")){
            textStyleName = textStyleName.substring(0,textStyleName.lastIndexOf("_text"));
        }
        String newStyleName = oriLineStyleName+"_"+textStyleName;
        StyleType bean =  styleMap.get().get(ElementEnum.line.name()+"#"+newStyleName);
        if(bean == null){
            bean =  sql("select * from style_type where element = 'line' and name = ? ").one(StyleType.class,newStyleName);
            if(bean == null){
                Long nextCode = sql("select ifnull(max(code),0)+1 from style_type where element = 'line'").one(Long.class);
                bean = new StyleType(ElementEnum.line,newStyleName,nextCode.intValue());
                super.insert(bean);
            }
        }
        styleMap.get().put(ElementEnum.line.name()+"#"+newStyleName,bean);
        return bean;
    }

    /**
     * 仅针对文本样式 与 dashLine
     * @param element
     * @param styleTypeName
     * @return
     */
    public StyleType getOrInsertStyle(ElementEnum element,String styleTypeName){
        Map<Integer,StyleType> styleTypeMap = textStyleThreadLocal.get();
        StyleType bean = null;
        Integer nextCode = 1;
        for(StyleType one:styleTypeMap.values()){
            if(one.getElement().equals(element) && one.getName().equals(styleTypeName)){
                bean = one;
            }
            if(one.getCode()!=null && one.getCode()>=nextCode ){
                nextCode = one.getCode()+1;
            }
        }
        if(nextCode <3000){
            nextCode = 3000;
        }
//        StyleType bean =  sql("select * from style_type where element = ? and name = ? ").one(StyleType.class,element.name(),styleTypeName);
//        Long nextCode = sql("select ifnull(max(code),0)+1 from style_type where element = ?").one(Long.class,element.name());
        if(bean !=null ){
//            StyleType sameCodeBean =  sql("select * from style_type where element = ? and code = ? and name != ?").one(StyleType.class,element.name(),bean.getCode(),styleTypeName);
            StyleType sameCodeBean = null;
            for(StyleType one:styleTypeMap.values()){
                if(element.equals(one.getElement()) && bean.getCode().equals(one.getCode()) && !styleTypeName.equals(one.getName())){
                    sameCodeBean = one;
                    break;
                }
            }
            if(sameCodeBean!=null){
                bean.setCode(nextCode);
                update(bean);
            }
        }
        if(bean == null){
            bean = new StyleType(element,styleTypeName,nextCode);
            super.insert(bean);
            styleTypeMap.put(bean.getId(),bean);
        }
        return bean;
    }


    public StyleType getStyleType(ElementEnum element, String styleTypeName) {
        if(StringUtils.isEmpty(styleTypeName)){
            return null;
        }
        StyleType type = styleMap.get().get(element.name()+"#"+styleTypeName);
        return type;
    }

    public void saveInstanceStyle(Integer instanceId) {
        List<InstanceStyle> instanceStyleList = new ArrayList<>();
        for(StyleType styleType:styleMap.get().values()) {
            if(styleType.getElement() == null){
                //图标样式不存全局，而是存 instance_icon
                continue;
            }
            if(styleType.getElement().getType()!=null && styleType.getElement().getType()>0){
                InstanceStyle instanceStyle = new InstanceStyle();
                instanceStyle.setInstanceId(instanceId);
                instanceStyle.setStyleTypeId(styleType.getId());
                instanceStyle.setTagForModify(styleType.getTagForModify());
                instanceStyle.setTextTag(styleType.getTextTag());
                instanceStyle.setTextTypeId(styleType.getTextTypeId());
                instanceStyleList.add(instanceStyle);
            }
        }
        saveOrUpdateAll(instanceStyleList);
    }

    public void updateInstanceStyle(String field, String fieldVal, Integer styleTypeId, Integer instanceId) {
       InstanceStyle bean =  sql("select * from instance_style where instanceId = ? and styleTypeId = ? ").one(InstanceStyle.class,instanceId,styleTypeId);
        if(bean == null){
            bean = new InstanceStyle();
            bean.setInstanceId(instanceId);
            bean.setStyleTypeId(styleTypeId);
            if(field.equals("textTag")){
                bean.setTextTag(fieldVal);
            }else{
                bean.setTagForModify(fieldVal);
            }
            insert(bean);
        }else {
            sql("update instance_style set "+field+" = ? where instanceId = ? and styleTypeId = ? ").update(new Object[]{fieldVal,instanceId,styleTypeId});
        }
    }

    public StyleType getStyleType(Integer styleTypeId, List<StyleType> styleTypeList) {
        if(styleTypeId != null){
            for(StyleType item:styleTypeList){
                if(item.getId().equals(styleTypeId)){
                    return item;
                }
            }
        }
        return null;
    }



}
